package atlantik.ui;

import static atlantik.Log.warn;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;

import javax.swing.JOptionPane;
import javax.xml.parsers.ParserConfigurationException;

import monopd.Monopd;

import atlantik.ai.SimpleAI;
import atlantik.game.AbstractAtlantikListener;
import atlantik.game.Atlantik;
import atlantik.game.AtlantikClient;
import atlantik.game.AtlantikListenerDispatcher;

import gnu.getopt.Getopt;

import java.awt.Frame;

public class Main extends AbstractAtlantikListener {

	public static Monopd monopd = new Monopd();
	
	public static final String localhost = "127.0.0.1";
	
	private final AtlantikListenerDispatcher dispatcher = new AtlantikListenerDispatcher();
	
	private final Atlantik client;
	
	public static ConnectionDialog cd;
	
	private String name;

	private String cookie;
	
	private final GUI gui;

	private final TextUI tui;

	private final PrintWriter out;

	private SimpleAI ai;

	// see public static void main to enter your server information
	
	public static void main(String[] args) throws IOException,
			ParserConfigurationException
	{
		
		String name = null;
		String host = localhost;
		int port = 1234;
		boolean startAi = true;
		boolean startLocalServer = true;
		int botCount = 1;
		
		name = null;

		Getopt g = new Getopt("Gatoropoly", args, "a:b:h:m:n:p:");
		int c;

		// get arguments from command line.
		while ((c = g.getopt()) != -1) {
			switch (c) {
			case 'a':
				String tmp = g.getOptarg();
				if (tmp.compareTo("on") == 0)
					startAi = true;
				else if (tmp.compareTo("off") == 0)
					startAi = false;
				break;
			case 'b':
				botCount = Integer.parseInt(g.getOptarg());
				break;
			case 'h':
				host = g.getOptarg();
				break;
			case 'm':
				String mode = g.getOptarg();
				if (mode.compareTo("s") == 0)
					startLocalServer = true;
				else if (mode.compareTo("c") == 0)
					startLocalServer = false;
				break;
			case 'n':
				name = g.getOptarg();
				break;
			case 'p':
				port = Integer.parseInt(g.getOptarg());
				break;
			default:
				// bail out on a bad option.
				System.exit(1);
				break;
			}
		}

		/* start the connection dialog. This will start Main() */
		cd = new ConnectionDialog(host,
		    port, name, startAi, startLocalServer, botCount);
	}

	public Main(String host, int port, String name) throws IOException,
			ParserConfigurationException {
		String logfile = host + "_" + name + ".log";
		this.out = new PrintWriter(new FileWriter(logfile));
		this.name = name;
		this.client = new AtlantikClient(host, port, dispatcher);

		dispatcher.addListener(this);

		gui = new GUI(client);
		gui.setSize(700, 400);
		gui.setExtendedState(Frame.MAXIMIZED_BOTH);
		gui.setTitle("Gatoropoly - " + name);
		gui.setVisible(true);

		tui = new TextUI(client, dispatcher, new InputStreamReader(System.in),
				new OutputStreamWriter(System.out));
		tui.start();

		readCookie();

		Runtime.getRuntime().addShutdownHook(new Thread() {
			@Override
			public void run() {
					deleteCookie();
			}
		});
		client.connect();
	}

	public void serverVersion(String version) {
		if (cookie != null)
			client.reconnect(cookie);
		else
			client.setName(name);
	}

	public void clientInfo(int playerId, String cookie) {
		if (this.cookie != null && !this.cookie.equals(cookie))
			client.setName(name);
		this.cookie = cookie;
		writeCookie();
		gui.loggedIn();
		gui.setState(new ConnectedState(client));
	}

	public void xml(String xml) {
		out.println(xml);
		out.flush();
	}

	void writeCookie() {
		PrintWriter out = null;
		try {
			out = new PrintWriter(new OutputStreamWriter(new FileOutputStream(
					name + ".cookie")));
			out.println(cookie);
		} catch (IOException e) {
			warn("Could not write cookie");
		}
		if (out != null)
			out.close();
	}

	void deleteCookie() {
		new File(name + ".cookie").delete();
	}

	public void startAi() {
		if (this.ai != null)
			dispatcher.removeListener(ai);
		ai = new SimpleAI(client, dispatcher);
	}

	void readCookie() {
		BufferedReader in = null;
		try {
			in = new BufferedReader(new InputStreamReader(new FileInputStream(
					name + ".cookie")));
			this.cookie = in.readLine();
		} catch (IOException e) {
			warn("Could not read cookie");
		}
		if (in != null)
			try {
				in.close();
			} catch (IOException e) {
			}
	}
	//This method returns the clients GUI handle 
	//Added by Eddie Martinez for Standalone req.
	public GUI returnHandle()
	{
		return this.gui;
	}
	
}
